local assets =
{

}

local prefabs =
{

}

local function GetStringsTable(inst)
    return TUNING.NPC_CHAT_TABLE[ inst.npc_base_lib:Get_Language() ] ["npc_item_tree_trade_station"] or {}
end

local function chop_tree(inst, chopper, chopsleft, numchops)
    if not (chopper ~= nil and chopper:HasTag("playerghost")) then
        inst.SoundEmitter:PlaySound(
            chopper ~= nil and chopper:HasTag("beaver") and
            "dontstarve/characters/woodie/beaver_chop_tree" or
            "dontstarve/wilson/use_axe_tree"
        )
    end

    inst.AnimState:PlayAnimation("hit")
    inst.AnimState:PushAnimation("idle", true)

    local x, y, z = inst.Transform:GetWorldPosition()
    SpawnPrefab(math.random() < 0.5 and "orange_leaves_chop" or "yellow_leaves_chop").Transform:SetPosition(x, y + math.random(), z)
end

local function chop_down_tree_shake(inst)
	inst.SoundEmitter:PlaySound("summerevent/plaza/hit")
    ShakeAllCameras(CAMERASHAKE.FULL, .25, .03, .5, inst, 6)
end

local function chop_down_tree(inst, chopper)
    local pt = inst:GetPosition()

    local he_right = true
    if chopper then
        local hispos = chopper:GetPosition()
        he_right = (hispos - pt):Dot(TheCamera:GetRightVec()) > 0
    else
        if math.random() > 0.5 then
            he_right = false
        end
    end
    if he_right then
        inst.AnimState:PlayAnimation("fallright")
        inst.components.lootdropper:DropLoot(pt - TheCamera:GetRightVec())
        inst.SoundEmitter:PlaySound("summerevent/plaza/fall")
    else
        inst.AnimState:PlayAnimation("fallleft")
        inst.components.lootdropper:DropLoot(pt + TheCamera:GetRightVec())
        inst.SoundEmitter:PlaySound("summerevent/plaza/fall")
    end

	if inst.components.activatable ~= nil then
		inst.components.activatable.inactive = false
	end

	inst._choppeddown = true

	inst:RemoveTag("shelter")

	inst.persists = false
	inst:DoTaskInTime(14*FRAMES, chop_down_tree_shake)
	inst:ListenForEvent("animover", inst.Remove)
end

local function UpdateArtForRank(inst, rank, prev_rank, snap_animations)

	if rank >= 3 then
		if not snap_animations and inst.entity:IsAwake() then
			inst.AnimState:PlayAnimation("upgrade_2to3")
			inst.AnimState:PushAnimation("idle", true)
			inst.SoundEmitter:PlaySound("summerevent/plaza/upgrade_2to3")
		end

		inst.AnimState:Hide("trunk")
		inst.AnimState:Show("trunk_painted")

		inst.AnimState:Show("level2")
		inst.AnimState:Show("level3")

	elseif rank == 2 then
		if not snap_animations and inst.entity:IsAwake() then
			if rank > prev_rank then
				inst.AnimState:PlayAnimation("upgrade_1to2")
				inst.AnimState:PushAnimation("idle", true)
				inst.SoundEmitter:PlaySound("summerevent/plaza/upgrade_1to2")
			else
				inst.AnimState:PlayAnimation("downgrade_3to2")
				inst.AnimState:PushAnimation("idle", true)
				inst.SoundEmitter:PlaySound("summerevent/plaza/downgrade_3to2")
			end
		end

		inst.AnimState:Hide("trunk")
		inst.AnimState:Show("trunk_painted")

		inst.AnimState:Show("level2")
		inst.AnimState:Hide("level3")
	else -- rank == 1
		if not snap_animations and inst.entity:IsAwake() then
			if rank < prev_rank then
				inst.AnimState:PlayAnimation("downgrade_2to1")
				inst.AnimState:PushAnimation("idle", true)
				inst.SoundEmitter:PlaySound("summerevent/plaza/downgrade_2to1")
			end
		end

		inst.AnimState:Hide("trunk_painted")
		inst.AnimState:Show("trunk")

		inst.AnimState:Hide("level2")
		inst.AnimState:Hide("level3")
	end

end

local function onbuilt(inst, data)
	local rot = data ~= nil and data.rot or 0
	inst.Transform:SetRotation(rot)

    inst.AnimState:PlayAnimation("place")
    inst.AnimState:PushAnimation("idle", true)
    inst.SoundEmitter:PlaySound("summerevent/plaza/place")
end

local function CreateFloor(parent)
	local inst = CreateEntity()

	--[[Non-networked entity]]
	inst.entity:SetCanSleep(false)
	inst.persists = false

	inst.entity:AddTransform()
	inst.entity:AddAnimState()

	inst:AddTag("CLASSIFIED")
	inst:AddTag("NOCLICK")
	inst:AddTag("DECOR")
	inst:AddTag("event_trigger")

	--local s = .9
	--inst.Transform:SetScale(s, s, s)

	inst.AnimState:SetBank("carnival_plaza_floor")
	inst.AnimState:SetBuild("carnival_plaza_floor")
	inst.AnimState:PlayAnimation("idle")
	inst.AnimState:SetOrientation(ANIM_ORIENTATION.OnGround)
    inst.AnimState:SetLayer(LAYER_BACKGROUND)
	inst.AnimState:SetSortOrder(-2)

	inst.entity:SetParent(parent.entity)
	if parent.components.placer ~= nil then
		parent.components.placer:LinkEntity(inst, 0.25)
	end

	inst:ListenForEvent("onbuilt", function() inst.AnimState:PlayAnimation("place") inst.AnimState:PushAnimation("idle", false) end, parent)

	return inst
end


-- local function OnActivate(inst, doer)
-- 	if inst._choppeddown then
-- 		return false
-- 	end

-- 	inst.AnimState:PlayAnimation("ringing")
-- 	inst.SoundEmitter:PlaySound("summerevent/plaza/ringing")
-- 	inst.AnimState:PushAnimation("idle", true)
	
-- 	inst.components.activatable.inactive = true
--     if TheWorld.components.carnivalevent then
--         return TheWorld.components.carnivalevent:SummonHost(inst)
--     end
--     return false, "NOCARNIVAL"
-- end

-- Deploy helper ring that shows up when placing decor items
local function DeployHelperRing_OnUpdate(helperinst)
	helperinst.parent.highlited = nil

	if not helperinst.placerinst:IsValid() then
		helperinst.components.updatelooper:RemoveOnUpdateFn(DeployHelperRing_OnUpdate)
		helperinst.AnimState:SetAddColour(0, 0, 0, 0)
	elseif helperinst.placerinst:GetCurrentPlatform() == nil and helperinst:IsNear(helperinst.placerinst, TUNING.CARNIVAL_DECOR_RANK_RANGE) then
		helperinst.AnimState:SetAddColour(.25, .75, .25, 0)
		helperinst.parent.highlited = true
	else
		helperinst.AnimState:SetAddColour(0, 0, 0, 0)
	end
end

local function CreateDeployHelperRing()
    local inst = CreateEntity()

    --[[Non-networked entity]]
    inst.entity:SetCanSleep(false)
    inst.persists = false

    inst.entity:AddTransform()
    inst.entity:AddAnimState()

    inst:AddTag("CLASSIFIED")
    inst:AddTag("NOCLICK")
    inst:AddTag("placer")

    inst.AnimState:SetBank("firefighter_placement")
    inst.AnimState:SetBuild("firefighter_placement")
    inst.AnimState:PlayAnimation("idle")
    inst.AnimState:SetAddColour(0, .2, .5, 0)
    inst.AnimState:SetLightOverride(1)
    inst.AnimState:SetOrientation(ANIM_ORIENTATION.OnGround)
    inst.AnimState:SetLayer(LAYER_WORLD_BACKGROUND)
    inst.AnimState:SetSortOrder(3)
	inst.AnimState:SetScale(1.3, 1.3)

    return inst
end

local function OnEnableHelper(inst, enabled, recipename, placerinst)
	if enabled then
		if inst.helper == nil then
			inst.helper = CreateDeployHelperRing()
			inst.helper.parent = inst
			inst.helper.entity:SetParent(inst.entity)
			if placerinst ~= nil then
				inst.helper:AddComponent("updatelooper")
				inst.helper.components.updatelooper:AddOnUpdateFn(DeployHelperRing_OnUpdate)
				inst.helper.placerinst = placerinst
				DeployHelperRing_OnUpdate(inst.helper)
			end
		end
	elseif inst.helper ~= nil then
		inst.helper:Remove()
		inst.helper = nil
	end
end
-----------------------------------------------------------------------------------------------
----- 定期铃声
local function RingSound_Task(inst)
    inst:DoPeriodicTask(10,function()
        if inst:IsNearPlayer(10) == false then
            return
        end
        inst:DoTaskInTime(math.random(7),function()
			if not inst:IsValid() then
				return
			end
            -- inst.AnimState:PlayAnimation("ringing")
            -- inst.SoundEmitter:PlaySound("summerevent/plaza/ringing")
            -- inst.AnimState:PushAnimation("idle", true)
			inst:PushEvent("ring")
        end)


    end)
    
end
-----------------------------------------------------------------------------------------------
--- 灯光相关的控制
-- FRAMES
local function Light_Task_Start(inst)
	if not TheWorld.ismastersim then
		return
	end
	-- TheWorld.state.isday
	-- TheWorld.state.isdusk
	-- TheWorld.state.isnight
	local delta_num = 0.0025
	if TheWorld.state.isnight == true or TheWorld:HasTag("cave") then
		-- print("info:Light_Task_Start  On",inst.__light_up_num)

		----------------------------------------------------------
		-- 关掉旧的任务
		if inst.__light_up_task ~= nil then
			inst.__light_up_task:Cancel()
			inst.__light_up_task = nil
		end
		if inst.__light_off_task ~= nil then
			inst.__light_off_task:Cancel()
			inst.__light_off_task = nil
		end
		-----------------------------------------------------------

		inst.Light:Enable(true)
		if inst.__light_up_num == nil then
			inst.__light_up_num = 0
		end

		inst.__light_up_task = inst:DoPeriodicTask(FRAMES,function()
			if inst.__light_up_num >= 0.9001 then
				inst.__light_up_task:Cancel()
				inst.__light_up_task = nil
				return
			end
			inst.Light:SetIntensity(inst.__light_up_num )
			inst.__light_up_num = inst.__light_up_num + delta_num
		end)
	elseif TheWorld.state.isday then	----------------- light  off
		-- print("info:Light_Task_Start  off")

		if inst.__light_up_task then
			inst.__light_up_task:Cancel()
			inst.__light_up_task = nil
		end

		if inst.__light_up_num == nil or inst.__light_up_num <= 0 then
			inst.Light:Enable(false)
			return
		end

		if inst.__light_up_num > 0 then
			inst.__light_off_task = inst:DoPeriodicTask(FRAMES,function()
				if inst.__light_up_num < 0 then
					inst.Light:Enable(false)
					if inst.__light_off_task then
						inst.__light_off_task:Cancel()
						inst.__light_off_task = nil
					end
					return
				end
				inst.Light:SetIntensity(inst.__light_up_num)
				inst.__light_up_num = inst.__light_up_num  - delta_num
			end)
		end
	else


	end
end
-----------------------------------------------------------------------------------------------

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddMiniMapEntity()
	inst.entity:AddNetwork()
	inst.entity:AddLight()
	
	-----------------------------------------------------------------------------------------------
	inst.MiniMapEntity:SetPriority(5)
    inst.MiniMapEntity:SetIcon("carnival_plaza.png")
	-----------------------------------------------------------------------------------------------
	-- inst.__light_up_num = 0
	-- inst.Light:SetIntensity(0.9)		-- 强度
	inst.Light:SetIntensity(0)		-- 强度
    inst.Light:SetRadius(5)			-- 半径 ，矩形的？？ --- SetIntensity 为1 的时候 成矩形
    inst.Light:SetFalloff(.4)		-- 下降梯度
    inst.Light:SetColour(255 / 255, 165 / 255, 0 / 255)
    inst.Light:Enable(false)
    -- inst.Light:EnableClientModulation(true)
	inst:DoTaskInTime(3,function()
		Light_Task_Start(inst)
	end)
	-----------------------------------------------------------------------------------------------


    MakeObstaclePhysics(inst, .4)


    inst.AnimState:SetBank("carnival_plaza")
    inst.AnimState:SetBuild("carnival_plaza")
    inst.AnimState:PlayAnimation("idle", true)

	-- inst:AddTag("carnivaldecor_ranker")
	-- inst:AddTag("carnival_plaza")
    inst:AddTag("structure")
	-- inst:AddTag("carnivalgame_part")
    -- inst:AddTag("shelter")

    MakeSnowCoveredPristine(inst)

    inst.entity:SetPristine()





	if not TheNet:IsDedicated() then    ------------- 地板创建用的代码
		CreateFloor(inst)

		inst:AddComponent("deployhelper")
		inst.components.deployhelper:AddKeyFilter("carnival_plaza_decor")
		inst.components.deployhelper.onenablehelper = OnEnableHelper
	end

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("npc_base_lib")
    inst:AddComponent("npc_everything_data")



    inst:AddComponent("inspectable")

    inst:AddComponent("named")
    inst.components.named:SetName(GetStringsTable(inst).tree_name)
    STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_tree_trade_station")] = GetStringsTable(inst).inspect_str  --人物检查的描述

    inst:AddComponent("savedrotation")
	inst:AddComponent("lootdropper")
    inst.components.lootdropper:SetLoot({"npc_item_tree_trade_station_kit"})

	inst:AddComponent("workable")
	inst.components.workable:SetWorkAction(ACTIONS.CHOP)
    inst.components.workable:SetOnWorkCallback(chop_tree)
    inst.components.workable:SetOnFinishCallback(chop_down_tree)

    MakeSnowCovered(inst)

	UpdateArtForRank(inst, 1, 1, true)
	-- UpdateArtForRank(inst, 2, 1, true)
	-- UpdateArtForRank(inst, 3, 2, true)


    inst:ListenForEvent("onbuilt", onbuilt)

    RingSound_Task(inst)
	inst:ListenForEvent("ring",function()
		inst.AnimState:PlayAnimation("ringing")
		inst.SoundEmitter:PlaySound("summerevent/plaza/ringing")
		inst.AnimState:PushAnimation("idle", true)
	end)

	require("prefabs/items/03_tree_trade_station_events")():Init(inst)

	-----------------------------------------------------------------------------------
	-- updatelight(inst)
	inst:WatchWorldState("cycles",function()	-------- 第二天
		inst:DoTaskInTime(10,function()
			Light_Task_Start(inst)			
		end)
	end)
	-- inst:WatchWorldState("isdusk",function()	-------- 黄昏
	-- 	inst:DoTaskInTime(10,function()
	-- 		updatelight(inst)			
	-- 	end)
	-- end)
	inst:WatchWorldState("isnight",function()	-------- 晚上
		if TheWorld.state.isnight then
			inst:DoTaskInTime(3,function()
				Light_Task_Start(inst)			
			end)
		end
	end)
	-----------------------------------------------------------------------------------
    return inst
end

local deployable_data = ------ 放置物品的inst的创建,MakeDeployableKitItem 调用的 fn
{
	deploymode = DEPLOYMODE.CUSTOM,
	custom_candeploy_fn = function(inst, pt, mouseover, deployer)   --- 放置时候的检查fn
        -- function Map:IsDeployPointClear(pt, inst, min_spacing, min_spacing_sq_fn, near_other_fn, check_player, custom_ignore_tags)
        local min_spacing = 7   --- 半径
		local ignore_tag = {"player","INLIMBO","FX","animal","smallcreature","flight","character","smallcreature","insect","companion","invisible","chester","hutch"}
        return TheWorld.Map:IsDeployPointClear(pt,inst,min_spacing,nil,nil,nil,ignore_tag)


        -- return false	
    end,

    master_postinit = function(inst)

        inst:AddComponent("npc_base_lib")
        inst:AddComponent("npc_everything_data")


        inst.components.inventoryitem:ChangeImageName("carnival_plaza_kit") --- 设置物品在背包里的贴图
        
        
        inst:AddComponent("named")
        inst.components.named:SetName(GetStringsTable(inst).tree_name)
        STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_tree_trade_station_kit")] = GetStringsTable(inst).kit_inspect_str  --人物检查的描述

		-- inst:ListenForEvent("onpickup",function()
		-- 	inst.npc_base_lib:Announce("66666666")
		-- end)
		inst.OnBuiltFn = function(inst,builder)
			if builder.npc_base_lib and builder.npc_everything_data and builder.npc_everything_data:Get("first.npc_item_tree_trade_station.build") ~= true then
				builder.npc_everything_data:Set("first.npc_item_tree_trade_station.build",true)
				builder.npc_base_lib:Wisper(GetStringsTable(builder).announce)
			end
		end
    end,
}


local function placer_postinit_fn(inst)
	UpdateArtForRank(inst, 1, 1, true)	--- 放置的时候只显示阶段1
    CreateFloor(inst)
	-- inst:AddComponent("npc_base_lib")
	-- inst.npc_base_lib = inst.components.npc_base_lib
	-- local chat_table = GetStringsTable(inst)
	-- inst.npc_base_lib:Announce(chat_table.announce)
end

return Prefab("npc_item_tree_trade_station", fn, assets, prefabs),
		MakeDeployableKitItem("npc_item_tree_trade_station_kit", "npc_item_tree_trade_station", "carnival_plaza", "carnival_plaza", "kit_item", assets, {size = "med", scale = 0.77}, nil, {fuelvalue = TUNING.LARGE_FUEL}, deployable_data),
		MakePlacer("npc_item_tree_trade_station_kit_placer", "carnival_plaza", "carnival_plaza", "idle", nil, nil, nil, nil, 90, nil, placer_postinit_fn)
